package model

import (
	"encoding/base64"
	"encoding/json"
	"github.com/BSNDA/PCNGateway-Go-SDK/pkg/core/config"
	"github.com/spf13/viper"
	"math/rand"
	"time"
	//"github.com/BSNDA/PCNGateway-Go-SDK/pkg/client"
	"github.com/BSNDA/PCNGateway-Go-SDK/pkg/client/fabric"
	//"github.com/BSNDA/PCNGateway-Go-SDK/pkg/client/fabric"
	//noderes "github.com/BSNDA/PCNGateway-Go-SDK/pkg/core/entity/res/fabric/node"
	"fmt"
	//"github.com/jinzhu/gorm"
	_ "github.com/jinzhu/gorm/dialects/mysql"
	"github.com/BSNDA/PCNGateway-Go-SDK/pkg/core/entity/req/fabric/node"
	//	"github.com/spf13/viper"
	"log"
	//	"github.com/BSNDA/PCNGateway-Go-SDK/pkg/client/fabric"
)


type Adresses struct {
	Node string `json:"node"`
	NextAdr string `json:"nextadr"`
}
type OrderInfo struct{
	OrderId string `json:"orderid"`
	Adresses []Adresses `json:"adresses"`
}

type BcQuery struct {
	OrderId string `json:"OrderId"`    //订单号
	Node string  `json:"Node"`    //当前地址
}


type BCMessage struct {
	Body string
}


//下一站地址查询操作
func  GetAdress(data string) (string, error) {
	rand.Seed(time.Now().UnixNano())//放在最外层
	bytes:=RandomByte(24)
	nonce:=Base64Encrypt(bytes)
	var  trans  node.TransReqDataBody
	var messages BCMessage
	var  test1 =[]string {data}
	trans.Args=test1   //通过key查values
	trans.ChainCode=viper.GetString("bc.chaincode")
	trans.FuncName="GetAdress"
	trans.Nonce=nonce
	//fbclient :=fabric.FabricClient{}
	   client:=BCinit()
	res,err  := client.ReqChainCode(node.TransReqDataBody(trans))
	if err != nil {
		log.Fatal(err)
	}
    messages.Body=res.Body.CCRes.CCData
    return messages.Body,nil
}

//测试get
func  Get1() (string, error) {
	rand.Seed(time.Now().UnixNano())//放在最外层
	bytes:=RandomByte(24)
	nonce:=Base64Encrypt(bytes)

	var  trans  node.TransReqDataBody
	var messages BCMessage
	var  test1 =[]string {`{"OrderId":"sf00021","Node":"郑州"}`}
	fmt.Println(test1)
	trans.Args=test1   //通过key查values
	trans.ChainCode="cc_97d199d9d7ec49d49fbfa41c2ecabf64"
	trans.FuncName="get"
	trans.Nonce=nonce
	//fbclient :=fabric.FabricClient{}
	client:=BCinit()
	res,err  := client.ReqChainCode(node.TransReqDataBody(trans))
	if err != nil {
		log.Fatal(err)
	}
	messages.Body=res.Body.CCRes.CCData
	return messages.Body,nil
}


//地址上链操作
func  SetAdress(message string ) (string, error) {
	//随机数nonce生成
	rand.Seed(time.Now().UnixNano())//放在最外层
	bytes:=RandomByte(24)
	nonce:=Base64Encrypt(bytes)

	//传入string
	var orderdata = []string {message}
	var  trans  node.TransReqDataBody
	trans.Args=orderdata
	trans.ChainCode=viper.GetString("bc.chaincode")
	trans.FuncName="SetAdress"
	trans.Nonce=nonce
	client:=BCinit()
	res,err:=client.ReqChainCode(node.TransReqDataBody(trans))
	if err != nil {
		log.Fatal(err)
	}
	var messages BCMessage
	messages.Body=res.Body.CCRes.CCData
	return messages.Body,nil
}


//上链操作测试
func  Set1()  {
	//随机数nonce生成
	rand.Seed(time.Now().UnixNano())//放在最外层
	bytes:=RandomByte(24)
	nonce:=Base64Encrypt(bytes)

	//传入string
	var orderdata = []string {`{"BaseKey":"sf00012","BaseValue":[{"Node":"石家庄","NextAdr":"武汉"},{"Node":"武汉","NextAdr":"杭州"},{"Node":"杭州","NextAdr":"扬州"}]}`}
	var  trans  node.TransReqDataBody
	trans.Args=orderdata
	trans.ChainCode="cc_97d199d9d7ec49d49fbfa41c2ecabf64"
	trans.FuncName="set"
	trans.Nonce=nonce
	client:=BCinit()
	 client.ReqChainCode(node.TransReqDataBody(trans))


}


//前端字符串json解析操作
func Decode (body []byte ) OrderInfo {
	var oderinfo OrderInfo
	err1 := json.Unmarshal(body,&oderinfo)
	if err1 != nil {
		fmt.Println(err1)
	}
   return oderinfo
}

//生成24位伪随机数int
// Returns an int >= min, < max
func randomInt(min, max int) int {
	return min + rand.Intn(max-min)
}


// Generate a random string of A-Z chars with len = l
func RandomByte(len int) []byte {
	//将int转化为byte类型
	bytes := make([]byte, len)
	for i := 0; i < len; i++ {
		bytes[i] = byte(randomInt(65, 90))
	}
   // ms:= string(bytes)
	return bytes
}
//对随机数进行base64加密编码生成Nonce
func  Base64Encrypt(body []byte) string{
	encodeString := base64.StdEncoding.EncodeToString(body)
	return encodeString
}

//初始化客户端
func BCinit() *fabric.FabricClient {

	api := viper.GetString("bc.api")     //PCN gateway address
	userCode := viper.GetString("bc.userCode") //user code
	appCode := viper.GetString("bc.appCode")  //DApp code
	puk := "-----BEGIN PUBLIC KEY-----\nMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEV5+GtbQNzwfPsMfVIFNBg3xgRuwV\n2RDS+Rjd72F6qXGwrb8QLSDUitNinENWuowAEsu/U9GsfSn0A48xlRTfSg==\n-----END PUBLIC KEY-----"      //public key
	prk := "-----BEGIN PRIVATE KEY-----\nMIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQgVbS8svrC3sdFgIFW\nUoLfczfjCjq0z7fGTSFfqMkjssChRANCAARXn4a1tA3PB8+wx9UgU0GDfGBG7BXZ\nENL5GN3vYXqpcbCtvxAtINSK02KcQ1a6jAASy79T0ax9KfQDjzGVFN9K\n-----END PRIVATE KEY-----"      //private key
	mspDir := ""   //cert storage directory
	cert := ""     //cert

	config, err := config.NewConfig(api, userCode, appCode, puk, prk, mspDir, cert)
	if err != nil {
		log.Fatal(err)
	}
	client,err:=fabric.InitFabricClient(config)
	return client
}
